package com.lgh.ibs.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.lgh.ibs.constants.myenum.IbsMavenRootTypeEnum;
import com.lgh.ibs.constants.myenum.PomVersionLevelEnum;
import com.lgh.ibs.constants.myenum.VersionOptionCodeEnum;
import com.lgh.ibs.entity.IbsRootMaven;
import com.lgh.ibs.entity.MavenPom;
import com.lgh.ibs.log.IbsLogger;

/**
 * @ClassName: MavenPomUtil 
 * @Description: Maven pom文件操作工具
 * @date 2016年12月28日 上午11:24:10 
 * @author guohao.li
 */
public class MavenPomUtil {
	private static TransformerFactory transFactory=TransformerFactory.newInstance();
	private static DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	
	private static XPathFactory xpathFactory=XPathFactory.newInstance();
	private static XPath xpath=xpathFactory.newXPath();
	/**
	 * @Title: getMavenPom 
	 * @Description:获取Maven信息 
	 * @param pomFilePath
	 * @return
	 * @throws Exception
	 * @throws 
	 * @author guohao.li
	 * @dateTime 2016年12月28日 上午11:24:54
	 */
	
	public static MavenPom getMavenPom(String pomFilePath) throws Exception {
		DocumentBuilder builder = domFactory.newDocumentBuilder();
		Document document = builder.parse(new File(pomFilePath));
		
		String projectArtifactId = (String) xpath.evaluate("/project/artifactId/text()", document,  XPathConstants.STRING);
		String projectVersion = (String) xpath.evaluate("/project/version/text()", document,  XPathConstants.STRING);
		String projectName = (String) xpath.evaluate("/project/name/text()", document,  XPathConstants.STRING);
		String projectPackage = (String) xpath.evaluate("/project/packaging/text()", document,  XPathConstants.STRING);
		


		String parentGroupId = (String) xpath.evaluate("/project/parent/groupId/text()", document,  XPathConstants.STRING);
		String parentArtifactId = (String) xpath.evaluate("/project/parent/artifactId/text()", document,  XPathConstants.STRING);
		String parentVersion = (String) xpath.evaluate("/project/parent/version/text()", document,  XPathConstants.STRING);
		MavenPom mavenPom = new MavenPom();
		mavenPom.setProjectArtifactId(projectArtifactId);
		mavenPom.setProjectName(projectName);
		mavenPom.setProjectPackage(projectPackage);
		mavenPom.setProjectVersion(projectVersion);
		
		mavenPom.setParentArtifactId(parentArtifactId);
		mavenPom.setParentGroupId(parentGroupId);
		mavenPom.setParentVersion(parentVersion);
		
		IbsLogger.INFO("获取工程POM.xml信息： " + pomFilePath +  mavenPom);
		return mavenPom;
	}
	
	/**
	 * @Title: modifyPomVersion 
	 * @Description: 修改pom版本号（公供）
	 * @param versionNum 版本号
	 * @param versionLevel 版本级别 1
	 * @param optionType 操作类型  add +1，sub -1
	 * @return
	 * @throws Exception 
	 * @throws 
	 * @author guohao.li
	 * @dateTime 2016年12月27日 下午3:27:22
	 */
	public static String modifyPomVersion(String versionNum,Integer versionLevel, Integer
			optionType) throws Exception{
		String modifyVersion = null;
		try {
			//		1.12.0-SNAPSHOT
			if(versionNum != null && versionNum !=""){
				if(versionNum.contains("-SNAPSHOT")){
					String[] version = versionNum.split("-");
					modifyVersion = getModifyVersion(versionLevel, optionType, version[0]);
					modifyVersion= modifyVersion + "-SNAPSHOT";
				}else{
					modifyVersion = getModifyVersion(versionLevel, optionType, versionNum);
				}
			}
			
		} catch (Exception e) {
			IbsLogger.ERROR("操作版本号有错误", e);
			throw new Exception("操作版本号有错误！", e);
		}
		return modifyVersion;
	}

	private static String getModifyVersion(Integer versionLevel, Integer optionType, String version) {
		String[] levelArr = version.split("\\.");
		String maxNumber = levelArr[0];
		String minNumber = levelArr[1];
		String bugNumber = levelArr[2];
		
		if(PomVersionLevelEnum.MaxVersion.getCode().equals(versionLevel)){
			maxNumber = getLevelVersion(maxNumber, optionType);
		}
		if(PomVersionLevelEnum.MinVersion.getCode().equals(versionLevel)){
			minNumber = getLevelVersion(minNumber, optionType);
		}
		if(PomVersionLevelEnum.bugVersion.getCode().equals(versionLevel)){
			bugNumber = getLevelVersion(bugNumber, optionType);
		}
		
		levelArr[0] = maxNumber;
		levelArr[1] = minNumber;
		levelArr[2] = bugNumber;
		
		return getVersionStr(levelArr);
	}
	
	private static String getLevelVersion(String number, Integer optionType){
		Integer num =null;
		if(optionType.equals(VersionOptionCodeEnum.Add_1.getCode())){
			num = Integer.valueOf(number) + 1;
		}else if(optionType.equals(VersionOptionCodeEnum.Sub_1.getCode())){
			num = Integer.valueOf(number);
			if(num > 0){
				num = num - 1;
			}
		}
		return String.valueOf(num);
	}
	
	private static String getVersionStr(String[] arr){
		String str = "";
		for (String s : arr) {
			str += s+".";
		}
		if(str.endsWith(".")){
			str = str.substring(0, str.length()-1);
		}
		return str;
	}
	
	private static Node selectSingleNode(String express, Object source) throws Exception  {//查找节点，并返回第一个符合条件节点
		Node result=null;
		result=(Node) xpath.evaluate(express, source, XPathConstants.NODE);
		return result;
	}
	
	public static NodeList selectNodes(String express, Object source) throws Exception  {//查找节点，返回符合条件的节点集。
		NodeList result=null;
		result=(NodeList) xpath.evaluate(express, source, XPathConstants.NODESET);
		return result;
	}
	
	
	
	private static void saveXml(String fileName, Document doc) throws Exception {//将Document输出到文件
		Transformer transformer = transFactory.newTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");//增加换行缩进，但此时缩进默认为0
//		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");//设置缩进为2
		transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
		DOMSource source=new DOMSource();
		source.setNode(doc);
		StreamResult result=new StreamResult();
		result.setOutputStream(new FileOutputStream(fileName));
		
		transformer.transform(source, result);
		
	}
	
	/**
	 * @Title: modifyPomVersionByFile 
	 * @Description:修改Pom文件中节点 
	 * @param fileName 文件路径
	 * @param dataMap key:为xml的xpath路径表达式，value:为此表达工所对应 的节点的修改值 
	 * @throws Exception
	 * @throws 
	 * @author guohao.li
	 * @dateTime 2016年12月28日 上午11:28:02
	 */
	public static void modifyPomVersionByFile(String fileName, Map<String, String > dataMap) throws Exception {
		domFactory.setIgnoringElementContentWhitespace(false);
		DocumentBuilder documentBuilder = domFactory.newDocumentBuilder();
		Document xmldoc = documentBuilder.parse(new File(fileName));
		xmldoc.setXmlStandalone(true);
		xmldoc.setStrictErrorChecking(false);
		Element root = xmldoc.getDocumentElement();
		
		Set<String> keySet = dataMap.keySet();
		for (String key : keySet) {
			String value = dataMap.get(key);
			
			Element el= (Element) selectSingleNode(key, root);
			el.setTextContent(value);
		}
		
		saveXml(fileName, xmldoc); 
	}
	

	/**
	 * 获取root工程的版本信息
	 * @param pomFilePath
	 * @return
	 * @throws Exception 
	 */
	public static List<IbsRootMaven> getRootProjectChildrenVersionList(String pomFilePath) throws Exception {
		DocumentBuilder builder = domFactory.newDocumentBuilder(); 
		Document document = builder.parse(new File(pomFilePath));
		
		List<IbsRootMaven> list = new ArrayList<IbsRootMaven>();

		String rootArtifactId = (String) xpath.evaluate("/project/artifactId/text()", document,  XPathConstants.STRING);
		String rootVersion = (String) xpath.evaluate("/project/version/text()", document,  XPathConstants.STRING);
		IbsRootMaven rootMaven = new IbsRootMaven();
		rootMaven.setProjectName(rootArtifactId);
		rootMaven.setProjectVersion(rootVersion);
		rootMaven.setProjectType(IbsMavenRootTypeEnum.Root.getCode());
		
		list.add(rootMaven);
		NodeList selectNodes = selectNodes("/project/properties/*", document);
		if(selectNodes.getLength()==0){
			throw new Exception("root 的pom.xml 无 properties节点！");
		}
		for (int i = 0; i < selectNodes.getLength(); i++) {
			Node node = selectNodes.item(i); 
			
			String nodeName = node.getNodeName();
			//筛选出以ibs-开头的节点
			if(nodeName.toLowerCase().startsWith("ibs-")){
				String versionNumber = node.getTextContent();
				
				IbsRootMaven childrenMaven = new IbsRootMaven();
				childrenMaven.setProjectName(nodeName);
				childrenMaven.setProjectVersion(versionNumber);
				childrenMaven.setProjectType(IbsMavenRootTypeEnum.Children.getCode());
				list.add(childrenMaven);
			}
		}
		return list;
	}
	
	public static void main(String[] args) throws Exception {
		String[] s = new String[]{};
		System.out.println(getVersionStr(s));
	}
}
